#include "skinthresholddialog.h"
#include "ui_skinthresholddialog.h"

#include "../skindetector.h"
#include "../gestureutils.h"

using namespace mlgesture;

SkinThresholdDialog::SkinThresholdDialog(int cam_id, int low_skin, int upper_skin, int low_value, int upper_value,
										 QWidget *parent) throw (HandGestureException) :
    QDialog(parent),
	ui_(new Ui::skinThresholdDialog),
	camId_(cam_id)
{
    ui_->setupUi(this);
	if (low_skin < 0) {
		low_skin = SkinDetector::GSD_HUE_LT*2;
	}
	if (upper_skin < 0) {
		upper_skin = SkinDetector::GSD_HUE_UT*2;
	}
	if (low_value < 0) {
		low_value = SkinDetector::GSD_INTENSITY_LT;
	}
	if (upper_value < 0) {
		upper_value = SkinDetector::GSD_INTENSITY_UT;
	}
	ui_->lowSlider->setValue(low_skin);
	ui_->upperSlider->setValue(upper_skin);
	ui_->valLowSlider->setValue(low_value);
	ui_->valUpperSlider->setValue(upper_value);

	cap_.open(cam_id);
	if( !cap_.isOpened() )
	{
		throw HandGestureException("Could not initialize capturing..");
	}

	timer_ = new QTimer();
	connect(timer_, SIGNAL(timeout()), this, SLOT(process()));
	timer_->start(30);
}

SkinThresholdDialog::~SkinThresholdDialog()
{
	if (cap_.isOpened())
		cap_.release();
	delete timer_;
    delete ui_;
}

int SkinThresholdDialog::getLowThreshold() const {
	return ui_->lowSlider->value();
}

int SkinThresholdDialog::getUpperThreshold() const {
	return ui_->upperSlider->value();
}

int SkinThresholdDialog::getValueLowThreshold() const {
	return ui_->valLowSlider->value();
}

int SkinThresholdDialog::getValueUpperThreshold() const {
	return ui_->valUpperSlider->value();
}

void SkinThresholdDialog::process() throw (HandGestureException) {
	cap_ >> frame_;
	if( frame_.empty())
		throw HandGestureException("Could not capture a frame");

	flip(frame_, frame_,1);
	Mat tmp;
	cvtColor(frame_, tmp, CV_BGR2HSV);
	split(tmp, hsvChannels_);

	frameMask_ = hsvChannels_[0].clone();
	int low = ui_->lowSlider->value()/2;
	int upper = ui_->upperSlider->value()/2;
	int low_value = ui_->valLowSlider->value();
	int upper_value = ui_->valUpperSlider->value();
	Mat_<unsigned char>::iterator it = frameMask_.begin<unsigned char>(), it_end = frameMask_.end<unsigned char>(),
			it_val = hsvChannels_[2].begin<unsigned char>();
	for (; it != it_end; ++it, ++it_val) {
		if (low > upper) {
			if (*it < low && *it > upper)
				*it = 0;
			else *it = 255;
		}
		else {
			if (*it < low || *it > upper)
				*it = 0;
			else
				*it = 255;
		}
		if ((*it_val < low_value) || (*it_val > upper_value)) {
			*it = 0;
		}
	}

	Mat imgTmp;
	dilate(frameMask_, imgTmp, Mat());
	erode(imgTmp, frameMask_, Mat());

	ui_->imageLabel->setPixmap(QPixmap::fromImage(GestureUtils::convertMat2QImage(frame_).scaled(ui_->imageLabel->size(), Qt::KeepAspectRatio)));
	ui_->maskLabel->setPixmap(QPixmap::fromImage(GestureUtils::convertMat2QImage(frameMask_).scaled(ui_->imageLabel->size(), Qt::KeepAspectRatio)));
}
